<?xml version="1.0" encoding="UTF-8" ?>
<!--

    Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
    under one or more contributor license agreements. See the NOTICE file
    distributed with this work for additional information regarding copyright
    ownership. Camunda licenses this file to you under the Apache License,
    Version 2.0; you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.camunda.bpm.engine.impl.persistence.entity.EventSubscriptionEntity">

  <!-- DELETE -->

  <delete id="deleteEventSubscription" parameterType="org.camunda.bpm.engine.impl.persistence.entity.EventSubscriptionEntity">
    delete from ${prefix}ACT_RU_EVENT_SUBSCR where ID_ = #{id} and REV_ = #{revision}
  </delete>

  <!-- RESULTMAP -->

  <resultMap id="eventSubscriptionResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.EventSubscriptionEntity">
    <id property="id" column="ID_" jdbcType="VARCHAR" />
    <result property="revision" column="REV_" jdbcType="INTEGER" />
    <result property="eventType" column="EVENT_TYPE_" jdbcType="VARCHAR" />
    <result property="eventName" column="EVENT_NAME_" jdbcType="VARCHAR" />
    <result property="executionId" column="EXECUTION_ID_" jdbcType="VARCHAR" />
    <result property="processInstanceId" column="PROC_INST_ID_" jdbcType="VARCHAR" />
    <result property="activityId" column="ACTIVITY_ID_" jdbcType="VARCHAR" />
    <result property="configuration" column="CONFIGURATION_" jdbcType="VARCHAR" />
    <result property="created" column="CREATED_" jdbcType="TIMESTAMP" />
    <result property="tenantId" column="TENANT_ID_" jdbcType="VARCHAR"/>
  </resultMap>

  <!-- SELECT -->

  <select id="selectEventSubscription" parameterType="string" resultMap="eventSubscriptionResultMap">
    select * from ${prefix}ACT_RU_EVENT_SUBSCR where ID_ = #{id}
  </select>

  <select id="selectEventSubscriptionByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.EventSubscriptionQueryImpl" resultMap="eventSubscriptionResultMap">
  	<include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    select ${distinct} RES.*
    ${limitBetween}
    <include refid="selectEventSubscriptionByQueryCriteriaSql"/>
    ${orderBy}
    ${limitAfter}
  </select>

  <select id="selectEventSubscriptionCountByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.EventSubscriptionQueryImpl" resultType="long">
    ${countDistinctBeforeStart} RES.ID_ ${countDistinctBeforeEnd}
    <include refid="selectEventSubscriptionByQueryCriteriaSql"/>
    ${countDistinctAfterEnd}
  </select>

  <sql id="selectEventSubscriptionByQueryCriteriaSql">
    from ${prefix}ACT_RU_EVENT_SUBSCR RES

    <if test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; authCheck.authUserId != null">
      left join ${prefix}ACT_RU_EXECUTION EXECUTION
      on EXECUTION.ID_ = RES.EXECUTION_ID_

      left join ${prefix}ACT_RE_PROCDEF EXEC_PROCDEF
      on EXEC_PROCDEF.ID_ = EXECUTION.PROC_DEF_ID_

      left join ${prefix}ACT_RU_EXECUTION PROC_EXECUTION
      on PROC_EXECUTION.ID_ = RES.PROC_INST_ID_

      left join ${prefix}ACT_RE_PROCDEF PROCDEF
      on PROCDEF.ID_ = PROC_EXECUTION.PROC_DEF_ID_

      <if test="!authCheck.revokeAuthorizationCheckEnabled">
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.authCheckJoinWithoutOnClause" />
        AUTH ON (AUTH.RESOURCE_ID_ ${authJoinStart} RES.ID_ 
          ${authJoinSeparator} EXECUTION.ID_
          ${authJoinSeparator} PROCDEF.KEY_
          ${authJoinSeparator} PROC_EXECUTION.ID_
          ${authJoinSeparator} PROCDEF.KEY_
          ${authJoinSeparator} '*'
          ${authJoinEnd}
        )
      </if>
    </if>

    <where>
      <if test="eventSubscriptionId != null">
        RES.ID_ = #{eventSubscriptionId}
      </if>
      <if test="processInstanceId != null">
        and RES.PROC_INST_ID_ = #{processInstanceId}
      </if>
      <if test="executionId != null">
        and RES.EXECUTION_ID_ = #{executionId}
      </if>
      <if test="activityId != null">
        and RES.ACTIVITY_ID_ = #{activityId}
      </if>
      <if test="eventType != null">
        and RES.EVENT_TYPE_ = #{eventType}
      </if>
      <if test="eventName != null">
        and RES.EVENT_NAME_ = #{eventName}
      </if>
      <if test="isTenantIdSet">
        <if test="tenantIds != null &amp;&amp; tenantIds.length > 0">
          and ( RES.TENANT_ID_ in
          <foreach item="tenantId" index="index" collection="tenantIds"
                   open="(" separator="," close=")">
            #{tenantId}
          </foreach>
          <if test="includeEventSubscriptionsWithoutTenantId">
            or RES.TENANT_ID_ is null
          </if>
          )
        </if>
        <if test="tenantIds == null">
          and RES.TENANT_ID_ is null
        </if>
      </if>

      <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.queryAuthorizationCheck" />
      <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheck" />

    </where>
  </sql>

  <select id="selectSignalEventSubscriptionsByEventName" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select EVT.*
    from ${prefix}ACT_RU_EVENT_SUBSCR EVT
    left join ${prefix}ACT_RU_EXECUTION EXC on EVT.EXECUTION_ID_ = EXC.ID_
    where (EVENT_TYPE_ = 'signal')
      and (EVENT_NAME_ = #{parameter})
      and (EVT.EXECUTION_ID_ is null or EXC.SUSPENSION_STATE_ = 1)
    <bind name="columnPrefix" value="'EVT.'"/>
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheckWithPrefix" />
  </select>

  <select id="selectSignalEventSubscriptionsByEventNameAndTenantId" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select EVT.*
    from ${prefix}ACT_RU_EVENT_SUBSCR EVT
    left join ${prefix}ACT_RU_EXECUTION EXC on EVT.EXECUTION_ID_ = EXC.ID_
    where (EVENT_TYPE_ = 'signal')
      and (EVENT_NAME_ = #{parameter.eventName})
      and (EVT.EXECUTION_ID_ is null or EXC.SUSPENSION_STATE_ = 1)
      <if test="parameter.tenantId != null">
        and EVT.TENANT_ID_ = #{parameter.tenantId}
      </if>
      <if test="parameter.tenantId == null">
        and EVT.TENANT_ID_ is null
      </if>
  </select>

  <select id="selectSignalEventSubscriptionsByEventNameAndTenantIdIncludeWithoutTenantId" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select EVT.*
    from ${prefix}ACT_RU_EVENT_SUBSCR EVT
    left join ${prefix}ACT_RU_EXECUTION EXC on EVT.EXECUTION_ID_ = EXC.ID_
    where (EVENT_TYPE_ = 'signal')
      and (EVENT_NAME_ = #{parameter.eventName})
      and (EVT.EXECUTION_ID_ is null or EXC.SUSPENSION_STATE_ = 1)
      and (EVT.TENANT_ID_ = #{parameter.tenantId} or EVT.TENANT_ID_ is null)
  </select>

  <select id="selectSignalEventSubscriptionsByExecution" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EVENT_TYPE_ = 'signal')
    	and (EXECUTION_ID_ = #{parameter})
  </select>

  <select id="selectSignalEventSubscriptionsByNameAndExecution" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EVENT_TYPE_ = 'signal')
    	and (EXECUTION_ID_ = #{parameter.executionId})
    	and (EVENT_NAME_ = #{parameter.eventName})
  </select>

  <select id="selectEventSubscriptionsByExecution" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EXECUTION_ID_ = #{parameter})
  </select>

  <select id="selectEventSubscriptionsByProcessInstanceId"  resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (PROC_INST_ID_ = #{parameter})
  </select>

  <select id="selectEventSubscriptionsByExecutionAndType" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EVENT_TYPE_ = #{parameter.eventType})
    	and (EXECUTION_ID_ = #{parameter.executionId})
    <if test="parameter.lockResult">
      ${constant_for_update}
    </if>
  </select>

  <select id="selectEventSubscriptionsByExecutionAndType_mssql" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    <if test="parameter.lockResult">
      with (UPDLOCK, ROWLOCK)
    </if>
    where (EVENT_TYPE_ = #{parameter.eventType})
      and (EXECUTION_ID_ = #{parameter.executionId})
  </select>

  <select id="selectEventSubscriptionsByExecutionTypeAndActivity" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EVENT_TYPE_ = #{parameter.eventType})
    	and (EXECUTION_ID_ = #{parameter.executionId})
    	and (ACTIVITY_ID_ = #{parameter.activityId})
  </select>

  <select id="selectEventSubscriptionsByConfiguration" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EVENT_TYPE_ = #{parameter.eventType})
    	and (CONFIGURATION_ = #{parameter.configuration})
  </select>

  <select id="selectEventSubscriptionsByNameAndTenantId" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EVENT_TYPE_ = #{parameter.eventType})
    	and (EVENT_NAME_ = #{parameter.eventName})
      <if test="parameter.tenantId != null">
        and TENANT_ID_ = #{parameter.tenantId}
      </if>
      <if test="parameter.tenantId == null">
        and TENANT_ID_ is null
      </if>
  </select>

  <select id="selectEventSubscriptionsByNameAndExecution" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EVENT_TYPE_ = #{parameter.eventType})
    	and (EVENT_NAME_ = #{parameter.eventName})
    	and (EXECUTION_ID_ = #{parameter.executionId})
    <if test="parameter.lockResult">
      ${constant_for_update}
    </if>
  </select>

  <select id="selectEventSubscriptionsByNameAndExecution_mssql"  resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    <if test="parameter.lockResult">
      with (UPDLOCK, ROWLOCK)
    </if>
    where (EVENT_TYPE_ = #{parameter.eventType})
      and (EVENT_NAME_ = #{parameter.eventName})
      and (EXECUTION_ID_ = #{parameter.executionId})
  </select>

  <select id="selectMessageStartEventSubscriptionByName" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR RES
    where (EVENT_TYPE_ = 'message')
        and (EVENT_NAME_ = #{parameter})
        and EXECUTION_ID_ is null
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheck" />
  </select>

  <select id="selectMessageStartEventSubscriptionByNameAndTenantId" resultMap="eventSubscriptionResultMap" parameterType="string">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    where (EVENT_TYPE_ = 'message')
      and (EVENT_NAME_ = #{messageName})
      and EXECUTION_ID_ is null
      <if test="tenantId != null">
        and TENANT_ID_ = #{tenantId}
      </if>
      <if test="tenantId == null">
        and TENANT_ID_ is null
      </if>
  </select>

  <select id="selectConditionalStartEventSubscription" resultMap="eventSubscriptionResultMap" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR RES
    <if test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; authCheck.authUserId != null">
      inner join ${prefix}ACT_RE_PROCDEF P on RES.CONFIGURATION_ = P.ID_
      <if test="!authCheck.revokeAuthorizationCheckEnabled">
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.authCheckJoinWithoutOnClause" />
        AUTH ON (AUTH.RESOURCE_ID_ ${authJoinStart} P.KEY_ ${authJoinSeparator} '*' ${authJoinEnd})
      </if>
    </if>
    <where>
      (EVENT_TYPE_ = 'conditional')
      and EXECUTION_ID_ is null
      <if test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; authCheck.authUserId != null">
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.queryAuthorizationCheck" />
      </if>
      <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheck" />
    </where>
  </select>

  <select id="selectConditionalStartEventSubscriptionByTenantId" resultMap="eventSubscriptionResultMap" parameterType="string">
    select *
    from ${prefix}ACT_RU_EVENT_SUBSCR
    <if test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; !authCheck.revokeAuthorizationCheckEnabled &amp;&amp; authCheck.authUserId != null">
      inner join ${prefix}ACT_RE_PROCDEF P on RES.CONFIGURATION_ = P.ID_
      <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.authCheckJoinWithoutOnClause" />
      AUTH ON (AUTH.RESOURCE_ID_ ${authJoinStart} P.KEY_ ${authJoinSeparator} '*' ${authJoinEnd})
    </if>
    <where>
      (EVENT_TYPE_ = 'conditional')
      and EXECUTION_ID_ is null
      <if test="parameter.tenantId != null">
        and TENANT_ID_ = #{parameter.tenantId}
      </if>
      <if test="parameter.tenantId == null">
        and TENANT_ID_ is null
      </if>
      <if test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; !authCheck.revokeAuthorizationCheckEnabled &amp;&amp; authCheck.authUserId != null">
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.queryAuthorizationCheck" />
      </if>
    </where>
  </select>

  <!-- INSERT -->

  <insert id="insertEventSubscription" parameterType="org.camunda.bpm.engine.impl.persistence.entity.EventSubscriptionEntity">
 	insert into ${prefix}ACT_RU_EVENT_SUBSCR (
            ID_,
            EVENT_TYPE_,
           	EVENT_NAME_,
           	EXECUTION_ID_,
           	PROC_INST_ID_,
           	ACTIVITY_ID_,
           	CONFIGURATION_,
           	CREATED_,
            TENANT_ID_,
            REV_
    )
    values (#{id, jdbcType=VARCHAR},
            #{eventType, jdbcType=VARCHAR},
            #{eventName, jdbcType=VARCHAR},
            #{executionId, jdbcType=VARCHAR},
            #{processInstanceId, jdbcType=VARCHAR},
            #{activityId, jdbcType=VARCHAR},
            #{configuration, jdbcType=VARCHAR},
            #{created, jdbcType=TIMESTAMP},
            #{tenantId, jdbcType=VARCHAR},
            1
    )
  </insert>

  <!-- UPDATE -->

  <update id="updateEventSubscription" parameterType="org.camunda.bpm.engine.impl.persistence.entity.EventSubscriptionEntity">
    update ${prefix}ACT_RU_EVENT_SUBSCR
    <set>
       REV_ =  #{revisionNext, jdbcType=INTEGER},
       EVENT_NAME_ = #{eventName, jdbcType=INTEGER},
       EXECUTION_ID_ = #{executionId, jdbcType=INTEGER},
       PROC_INST_ID_ = #{processInstanceId, jdbcType=INTEGER},
       ACTIVITY_ID_ = #{activityId, jdbcType=INTEGER},
       CONFIGURATION_ = #{configuration, jdbcType=VARCHAR},
       CREATED_ = #{created, jdbcType=TIMESTAMP}
    </set>
    where ID_= #{id, jdbcType=VARCHAR}
      and REV_ = #{revision, jdbcType=INTEGER}
  </update>

</mapper>
